#version 450

layout(location=0) in vec3 v_LightDir;
layout(location=1) in vec3 v_Color;
layout(location=2) in vec2 v_Texcoord;
layout(location=3) in vec3 v_FragPos;
layout(location=4) in vec3 v_ViewPos;
layout(location=5) in vec3 v_Normal;
layout(location=6) in vec3 v_NormalTS;
layout(location=7) in vec3 v_TangentTS;
layout(location=8) in vec3 v_BitangentTS;

layout(set=1, binding=0, std140) uniform MaterialUbo{
    vec4 diffuseColor;
    vec4 specularColor;
    vec4 detailSettings;
    uint useVertexColor;
    uint diffuseSelect;
    uint specularSelect;
    uint normalSelect;
} materialUbo;

layout(set=1, binding=1) uniform sampler2D u_diffuseTexture;
layout(set=1, binding=2) uniform sampler2D u_specularTexture;
layout(set=1, binding=3) uniform sampler2D u_normalTexture;
layout(set=1, binding=4) uniform sampler2D u_detailTexture;
layout(set=1, binding=5) uniform sampler2D u_diffPalTexture;

layout(location=0) out vec4 fragColor;

vec4 PS_PalettizeColorVariationTexture(vec4 IN_diffuseColor) {
    vec4 OUT = IN_diffuseColor;

    const float texAlpha = floor(IN_diffuseColor.a * 255.01f);

    const float alphaMin = 32;
    const float alphaMax = 160;

    // shift range to <0; 1>
    float texAlpha0 = (texAlpha - alphaMin) / (alphaMax - alphaMin);

    // sample palette:
    const float paletteRow = 0.0f;	// this must be converted in higher CustomShaderFX code
    vec4 newDiffuse = texture(u_diffPalTexture, vec2(texAlpha0, paletteRow));

    if ((texAlpha >= (alphaMin/*+2*/)) && (texAlpha <= (alphaMax/*-2*/))) {
        // new: palette's works as a tint:
        OUT.rgb = IN_diffuseColor.rgb * newDiffuse.rgb;
        OUT.a	= 1.0f;
    }
    return OUT;
}

void main(){
    //fragColor = vec4(v_Color, 1.0);
    //fragColor = vec4(v_Texcoord, 1.0, 1.0);
    //fragColor = texture(u_normalTexture, v_Texcoord);

    vec3 lightColor = vec3(0.95, 0.95, 0.95);
    vec3 L = normalize(-v_LightDir);
    vec3 N = v_Normal;
    if (materialUbo.normalSelect == 1) {
        mat3 TBN = mat3(normalize(v_TangentTS), normalize(v_BitangentTS), normalize(v_NormalTS));
        vec3 normal = (texture(u_normalTexture, v_Texcoord).rgb * 2.0) - 1.0;
        N = normalize(TBN * normal);
    }
    vec3 V = normalize(v_ViewPos - v_FragPos);
    vec3 R = reflect(-L, N);

    vec3 ambient = 0.5 * lightColor;
    vec3 diffuse = max(0.0, dot(N, L)) * lightColor * 1.75;
    //vec3 specular = pow(max(dot(R, V), 0.0), 16.0) * lightColor;
    // blinn phong
    vec3 halfwayDir = normalize(L + V);
    vec3 specular = pow(max(dot(N, halfwayDir), 0.0), 16.0) * lightColor;

    vec4 diffuseColor = materialUbo.diffuseSelect == 1 ? texture(u_diffuseTexture, v_Texcoord) : vec4(materialUbo.diffuseColor.rgb, 1.0);
    //diffuseColor = materialUbo.diffPalSelect == 1 ? PS_PalettizeColorVariationTexture(diffuseColor) : diffuseColor;
    diffuseColor = PS_PalettizeColorVariationTexture(diffuseColor);
    diffuseColor = materialUbo.useVertexColor == 1 ? vec4(v_Color, 1.0) : diffuseColor;

    vec4 specularColor = materialUbo.specularSelect == 1 ? texture(u_specularTexture, v_Texcoord) : vec4(materialUbo.specularColor.rgb, 1.0);

    vec3 color = (ambient + diffuse) * diffuseColor.rgb + specular * specularColor.rgb;
    fragColor = vec4(color, 1.0);
}
